package controllers.commands
{
	import com.google.maps.InfoWindowOptions;
	import com.google.maps.LatLng;
	import com.google.maps.Map;
	import com.google.maps.MapMouseEvent;
	import com.google.maps.MapMoveEvent;
	import com.google.maps.overlays.Marker;
	import com.google.maps.overlays.MarkerOptions;
	import com.google.maps.overlays.Polyline;
	import com.google.maps.overlays.PolylineOptions;
	import com.google.maps.styles.FillStyle;
	import com.google.maps.styles.StrokeStyle;
	
	import flash.display.DisplayObject;
	import flash.display.MovieClip;
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.events.MouseEvent;
	import flash.events.TimerEvent;
	import flash.geom.Point;
	import flash.text.StyleSheet;
	import flash.text.TextFormat;
	import flash.utils.Timer;
	import flash.utils.setTimeout;
	
	import mx.controls.Button;
	import mx.core.UIComponent;
	import mx.utils.ArrayUtil;
	
	import controllers.commands.base.ICommand;
	import controllers.managers.LocationQueryManager;
	
	import event.LocationEvent;
	
	import model.context.TrackerContext;
	import model.filter.ProtocalFilter;
	import model.registry.ColorTable;
	
	import utils.DeviceParser;
	import utils.LogUtil;
	
	import view.MapCanvas;
	
	/**
	 * 执行回放命令
	 **/
	public class StartPositionCommand extends EventDispatcher implements ICommand
	{
		public static var NAME : String = "StartPositionCommand";
		
		[Bindable]
		public var currentPositionData:Object;
		private var locationManager:LocationQueryManager = null;
		
		private var pointMC:MovieClip;
		private var carMC:MovieClip = new car();
		private var manMC:MovieClip = null;
		private var dogMC:MovieClip = null;
		private var pauseButton:Button;
		private var playButton:Button;
		private var pointImg:UIComponent;
		
		private var effectIndex:int;
		private var speedValue:Number = 0;
		private var isPause:Boolean;
		private var toolTipStr : String = "";
		private var positionLineArray:Array;
		private var positionArray:Array;
		private var oldPositionData:Object;
		private var totalPositionObject:Object;
		private var isPlayingMove:Boolean;
		
		private var oldViewport:Point;
		private var currentViewport:Point;
		private var polylineOptions:PolylineOptions 
						= new PolylineOptions({strokeStyle: new StrokeStyle({color: 0xFF0000,thickness: 2,alpha: 0.7})});
		
		/**
		 * 是否是定位数据回放
		 **/
		private var isPlayback:Boolean = false;
		
		private var container:MapCanvas;
		private var map:Map;
		private var marker:Marker;
		
		private var timer:Timer;
		private var actionTimer:Timer;
		
		private var addressTextStr : String = "查询中...";
		private var context:TrackerContext;
		public function StartPositionCommand()
		{
		}
		
		/**
		 * 设置速度
		 **/
		public function setSpeed(speedValue:Number):void
		{
			if(actionTimer)
			{
				actionTimer.delay = 50 + speedValue*100;
				actionTimer.repeatCount = 5;
			}
		}
		
		/**
		 * 设置运动状态
		 **/
		public function setPauseState():void
		{
			if(isPlayingMove && timer)
			{
				isPause = true;
				isPlayback = false;
				setPlayButtonEnable(true);
			}
		}
		
		/**
		 * 运行
		 **/
		public function setPlayState():void
		{
			if(isPlayingMove && timer)
			{
				isPause = false;
				isPlayback = true;
				timer.start();
				setPlayButtonEnable(false);
			}
		}
		
		public function setContext(cxt:Object):void
		{
			context = TrackerContext(cxt);
			
			var view:UIComponent=null;
			if(context != null && context.mapCanvas != null)
			{
				view = context.mapCanvas;
				effectIndex = context.startEffectIndex;
				setView(view);
			}
			
			locationManager = new LocationQueryManager();
			locationManager.addEventListener(LocationQueryManager.EVENT_UPDATE, onLocationUpdateHandler);
		}
		
		private function setView(view:UIComponent):void
		{
			container = MapCanvas(view);
			map = container.map;
			pointImg = container.pointImg;
			pauseButton = container.pauseButton;
			playButton = container.playButton;
			carMC = container.carMC;
			manMC = container.manMC;
			dogMC = container.dogMC;
		}
		
		public function execute():void
		{
			destroyExecute();
			
			if(context != null && 
					context.totalPos != null)
			{
				setData(context.totalPos);
			}
			else
			{
				LogUtil.getInst().error("上下文不能为空!");
			}
		}
		
		/**
		 * 停止执行命令
		 * 1.回收资源
		 * 2.停止计数器
		 **/
		public function destroyExecute():void
		{
			if(timer != null && actionTimer != null)
			{
				resetAll();
				new ClearMapCommand(this.container).execute();
			}
		}
		
		/**
		 * 直接从位置信息数据开始
		 **/
		public function setPostionData(dataObj:Object):void
		{
			positionArray = mx.utils.ArrayUtil.toArray(dataObj);
			playDataByType(true);
		}
		
		private function setData(dataObj:Object):void
		{
			isPlayback = true;
			if(totalPositionObject && dataObj.map.length == 1
				&& totalPositionObject.map.length == 1 && dataObj.map[0].client_id == totalPositionObject.map[0].client_id)
			{
				totalPositionObject = dataObj;
				playDataByType(true,false);
			}else
			{
				totalPositionObject = dataObj;
				playDataByType(true);
			}
		}
		
//		/**
//		 * 更新地址信息
//		 **/ 
//		private function onLocationUpdateHandler(evt:Event):void
//		{
//			if(currentPositionData != null)
//			{
//				var addresText : String = LocationQueryManager(evt.currentTarget).formattedAddress;
//				var endLatLng:LatLng = new LatLng(currentPositionData.latitude,currentPositionData.longitude);
//				
//				var infoList : Array = currentPositionData.status_text;
//				var infoParser : DeviceParser = new DeviceParser(currentPositionData);
//				//准备备注信息
//				toolTipStr  = "";
//				toolTipStr += " 时间: "+Global.getTimeStrByTime(currentPositionData.dateline, true ) + " \n" ;
//				toolTipStr += " 方向: "+infoParser.getDirection() + "\n" ;
//				toolTipStr +=  " 时速: "+infoParser.getSpeed() + "KM/h\n" ;
//				toolTipStr += " 经度: "+infoParser.getLng() + "\n" ;
//				toolTipStr += " 纬度: "+infoParser.getLat() + "\n" ;
//				toolTipStr += " 地址: " + addresText + " \n" ;
//				
//				var tempStr : String = "";
//				if(infoList != null)
//				{
//					for (var ii:int=0;ii<infoList.length;ii++)
//					{
//						tempStr += infoList[ii] + " " ;
//					}
//					toolTipStr += " 状态: " + tempStr + "\n";
//				}
//				
//				var opObj:Object = { 
//					strokeStyle:new StrokeStyle({color: ColorTable.GREY}),
//					fillStyle: new FillStyle({color: ColorTable.DARK_RED, alpha: 1}),
//					radius: 12,
//					hasShadow: true,
//					label:"P"}
//				
////				var marker:Marker ;
//				if( marker == null )
//				{
//					marker  = new Marker(endLatLng, new MarkerOptions(opObj));   
//					marker.addEventListener(MapMouseEvent.ROLL_OVER, onDisplayLocInfoByState);
//					marker.addEventListener(MapMouseEvent.ROLL_OUT, function():void{ marker.closeInfoWindow(); });
//					map.addOverlay(marker);
//				}
////				else
////				{
////					if(map.getPaneManager() != null 
////						&& marker != null
////						&& marker.pane != null
////						&& map.getPaneManager().containsPane(marker.pane))
////					{
////						map.removeOverlay(marker);
////					}
////				}
//			}
//		}
		
		/**
		 * 更新地址信息
		 **/ 
		private function onLocationUpdateHandler(evt:Event):void
		{
			if(currentPositionData != null)
			{
				addressTextStr = LocationQueryManager(evt.currentTarget).formattedAddress;
				updateLocationTooltip();
			}
		}
		
		/**
		 * 结束动画，添加Marker
		 **/
		private function createMarkerWhenEnd():void
		{
			if(currentPositionData != null)
			{					
				isPlayback = false;
				var endLatLng:LatLng = new LatLng(currentPositionData.latitude,currentPositionData.longitude);										
				var opObj:Object = { 
					strokeStyle:new StrokeStyle({color: ColorTable.GREY}),
					fillStyle: new FillStyle({color: ColorTable.DARK_RED, alpha: 1}),
					radius: 12,
					hasShadow: true,
					label:"P"}
				
				
				if(marker == null)
				{
					marker = new Marker(endLatLng, new MarkerOptions(opObj));
					marker.addEventListener(MapMouseEvent.ROLL_OVER, onDisplayLocInfoByState);
					marker.addEventListener(MapMouseEvent.ROLL_OUT, function():void{ marker.closeInfoWindow(); });
					map.addOverlay(marker);						
				}					
			}
		}
		
		/**
		 * 根据状态显示相应的颜色
		 **/
		private function onDisplayLocInfoByState(evt:MapMouseEvent):void
		{
			var marker:Marker = evt.currentTarget as Marker;
			if ( marker != null  && currentPositionData != null )
			{
				updateLocationTooltip(marker);
				var contentStr:String = "";
				
				var contentStyle:StyleSheet = new StyleSheet();
				contentStyle.setStyle("color", "#00CC00"); 
				
				var contentFormat:TextFormat = new TextFormat();
				contentFormat.size = 12;
				contentFormat.color = ColorTable.BLACK;
				marker.openInfoWindow(new InfoWindowOptions({ content:toolTipStr,
					hasShadow : false,
					hasTail : false,
					width : 250,
					hasCloseButton : true,
					tailAlign : InfoWindowOptions.ALIGN_LEFT,
					pointOffset : new Point(130,130),
					contentFormat : contentFormat}));
			}				
		}
		
		/**
		 * 创建tooltips
		 **/
		private function updateLocationTooltip(currentItem:Object=null):void
		{
			if(currentPositionData != null)
			{					
				var endLatLng:LatLng = new LatLng(currentPositionData.latitude,currentPositionData.longitude);
				
				var infoList : Array = currentPositionData.status_text;
				var infoParser : DeviceParser = new DeviceParser(currentPositionData);
				//准备备注信息
				toolTipStr  = "";
				toolTipStr += " 时间: "+Global.getTimeStrByTime(currentPositionData.dateline, true ) + " \n" ;
				toolTipStr += " 方向: "+infoParser.getDirection() + "\n" ;
				toolTipStr +=  " 时速: "+infoParser.getSpeed() + "KM/h\n" ;
				toolTipStr += " 经度: "+infoParser.getLng() + "\n" ;
				toolTipStr += " 纬度: "+infoParser.getLat() + "\n" ;
				toolTipStr += " 地址: " + addressTextStr + " \n" ;
				
				var tempStr : String = "";
				if(infoList != null)
				{
					for (var ii:int=0;ii<infoList.length;ii++)
					{
						tempStr += infoList[ii] + " " ;
					}
					toolTipStr += " 状态: " + tempStr + "\n";
				}
				
//				this.container.toolTip = toolTipStr;
				
				//避免鼠标放置到marker上，tooltip也出现
				if (currentItem == null) {
					this.container.toolTip = toolTipStr;
				}
			}	
		}
		
		/**
		 * 播放轨迹
		 **/
		private function playDataByType(isRestart:Boolean=false,isClear:Boolean=true):void
		{
			if(Global.currentMapType == 1)
			{
				positionArray = totalPositionObject.map;
				
			}else 
			{
				positionArray = totalPositionObject.sat;
			}
						
			positionArray = positionArray.filter(ProtocalFilter.doFilterProtocal);			
			
			if(isRestart)
			{
				startPositionEffect(isClear);
			}else if(!isPlayingMove)
			{
//				setPositionLine();
			}
			
		}
		
		private function onEffectActionComplete(e:Event=null):void
		{
			timer.start();
		}
		private function onEffectAction(e:Event=null):void
		{
			pointMC.x = oldViewport.x + (currentViewport.x - oldViewport.x)*(actionTimer.currentCount/actionTimer.repeatCount);
			pointMC.y = oldViewport.y + (currentViewport.y - oldViewport.y)*(actionTimer.currentCount/actionTimer.repeatCount);
		}
		
		private function startPositionEffect(isClear:Boolean=true):void
		{
			if(isPlayingMove)
			{
				stopPositionEffect();
			}
			
			map.addEventListener(MapMoveEvent.MOVE_STEP,onMoveStep);
			map.addEventListener(MapMoveEvent.MOVE_END,onMoveEnd);
			
			if(isClear)
			{
				currentPositionData = null;
				oldPositionData = null;
				if(positionLineArray)
				{
					while(positionLineArray.length > 0)
					{
						var polyline:Polyline = positionLineArray.pop() as Polyline;						
						polyline.foreground.removeEventListener(MouseEvent.ROLL_OVER,onRollOverPolyLine);
						polyline.foreground.removeEventListener(MouseEvent.ROLL_OUT,onRollOutPoluLine);
						map.removeOverlay(polyline);
					}
					
//					if(map.getPaneManager() != null 
//						&& marker != null
//						&& marker.pane != null
//						&& map.getPaneManager().containsPane(marker.pane))
//					{
//						map.removeOverlay(marker);
//					}
				}
				
				positionLineArray = [];
			}
			
			
			if(!timer)
			{
				timer = new Timer(50,0);
				timer.addEventListener(TimerEvent.TIMER,onEffect);
			}
			
			if(!actionTimer)
			{
				actionTimer = new Timer(50 + speedValue*100,5);
				actionTimer.addEventListener(TimerEvent.TIMER,onEffectAction);
				actionTimer.addEventListener(TimerEvent.TIMER_COMPLETE,onEffectActionComplete);
			}
			
			timer.start();
			
			isPlayingMove = true;
			
			if(pointImg.numChildren > 0)
			{
				pointImg.removeChildAt(0);
				pointMC = null;
			}
			
			switch(int(totalPositionObject.display_id))
			{
				case 1:
					pointMC = carMC;
					pointImg.addChild(carMC);
					break;
				case 2:
					pointMC = manMC;
					pointImg.addChild(manMC);
					break;
				case 3:
					pointMC = dogMC;
					pointImg.addChild(dogMC);
					break;
				default:
					pointMC = carMC;
					//pointImg.addChild(carMC);
					break;
			}
			setPlayButtonEnable(false);
		}
		
		/**
		 *  设置按钮是否可用
		 **/
		private function setPlayButtonEnable(value:Boolean):void
		{
			pauseButton.mouseEnabled = !value;
			pauseButton.visible = !value;
			pauseButton.buttonMode = !value;
			playButton.mouseEnabled = value;
			playButton.visible = value;
			playButton.buttonMode = value;
		}
		
		
		private function onEffect(e:Event=null):void
		{
			if(isPause)
			{
				timer.stop();
				return;
			}
			if(effectIndex < positionArray.length)//if(effectIndex < 11)
			{
				if(currentPositionData)
				{
					oldPositionData = currentPositionData;
				}
				
				currentPositionData = positionArray[effectIndex];
				//派发事件，让侦听当前的物体改变状态
				
				dispatchEvent(new Event(LocationEvent.UPDATE_CURRENT_LOC));
				
				var endLatLng:LatLng = new LatLng(currentPositionData.latitude,currentPositionData.longitude);
				if(oldPositionData)
				{
					var startLatLng:LatLng = new LatLng(oldPositionData.latitude,oldPositionData.longitude);
					var polyline:Polyline = new Polyline([startLatLng,endLatLng],polylineOptions);
					
					
					//InteractiveObject(polyline).mouseEnabled = true;
					polyline.foreground.name = "p" + effectIndex;					
					polyline.foreground.addEventListener(MouseEvent.ROLL_OVER,onRollOverPolyLine);
					polyline.foreground.addEventListener(MouseEvent.ROLL_OUT,onRollOutPoluLine);
					positionLineArray.push(polyline);
					setTimeout(function ():void
					{
						map.addOverlay(polyline);
						
					},500);
					
					if(pointMC == carMC)
					{
						pointMC.rotation = currentPositionData.direction;
					}else
					{
						pointMC.scaleX = currentPositionData.direction <= 180 ? 1 : -1;
					}
					
					trace("latitude",currentPositionData.latitude,"longitude",currentPositionData.longitude);
					
					//polyline
					//actionTimer.start();
					
					if(currentPositionData.latitude != oldPositionData.latitude || currentPositionData.longitude != oldPositionData.longitude)
					{
						map.panTo(endLatLng);
						timer.stop();
					}
				}else
				{
					oldPositionData = currentPositionData;
					
					map.panTo(endLatLng);
					timer.stop();
				}
				effectIndex ++;
			}else
			{
				stopPositionEffect();
			}
		}
		
//		private function onRollOverPolyLine(e:MouseEvent):void
//		{
//			
//			var trackerLine:DisplayObject = e.target as DisplayObject;
//			
//			var effectI:int = int(trackerLine.name.substr(1));
//			var positionData:Object = positionArray[effectI];						
//			if(positionData)
//			{
//				locationManager.query( positionData.latitude + "," + positionData.longitude);			
//			}
//			
//			this.container.toolTip = toolTipStr;
//		}
		
		private function onRollOverPolyLine(e:MouseEvent):void
		{				
			//如果正在播放动画，则退出..
			if ( !isPlayback ) {
				var trackerLine:DisplayObject = e.target as DisplayObject;
				var effectI:int = int(trackerLine.name.substr(1));
				currentPositionData = positionArray[effectI];						
				if(currentPositionData)
				{
					locationManager.query( currentPositionData.latitude + "," + currentPositionData.longitude);			
				}		
			} else {
				trace("正在播放轨迹动画中，稍后....");				
			}
		}
		
		private function onRollOutPoluLine(e:MouseEvent):void
		{
			this.container.toolTip = "";
		}
		
		/**
		 * 重置资源
		 **/
		private function resetAll():void
		{
			isPlayback = false;
			timer.stop();
			actionTimer.stop();
			isPlayingMove = false;
			map.removeEventListener(MapMoveEvent.MOVE_STEP,onMoveStep);
			map.removeEventListener(MapMoveEvent.MOVE_END,onMoveEnd);
			
			if(pointImg.numChildren > 0)
			{
				pointImg.removeChildAt(0);
				pointMC = null;
			}
		}
		
		/**
		 * 结束动画效果后
		 **/
		private function stopPositionEffect():void
		{
			resetAll();
			if(currentPositionData)
			{
				createMarkerWhenEnd();
				locationManager.query( currentPositionData.latitude + "," + currentPositionData.longitude);			
			}
		}
		
		private function onMoveStep(e:MapMoveEvent):void
		{
			//				trace("onMoveStep");
			if(pointMC)
			{
				if(isPlayingMove && oldPositionData)
				{
					oldViewport = map.fromLatLngToViewport(new LatLng(oldPositionData.latitude,oldPositionData.longitude));
					pointMC.x = oldViewport.x;
					pointMC.y = oldViewport.y;
					//						trace("onMoveStep",oldViewport.x,oldViewport.y);
				}else if(currentPositionData)
				{
					currentViewport = map.fromLatLngToViewport(new LatLng(currentPositionData.latitude,currentPositionData.longitude));
					pointMC.x = currentViewport.x;
					pointMC.y = currentViewport.y;
				}
				
			}
		}
		
		private function onMoveEnd(e:MapMoveEvent):void
		{
			if(isPlayingMove && oldPositionData && currentPositionData)
			{
				oldViewport = map.fromLatLngToViewport(new LatLng(oldPositionData.latitude,oldPositionData.longitude));
				currentViewport = map.fromLatLngToViewport(new LatLng(currentPositionData.latitude,currentPositionData.longitude));
				actionTimer.reset();
				actionTimer.start();
			}
			
		}
	}
}